package com.leetone;


/**
* @ClassName: Count
* @Description: 【单个用户干活类,如果不加同步锁synchronized，那么就会出现不安全的问题，最终的结果也是不定的】
* @date 2018年8月28日 下午5:59:36
* @Company: 上海未泰信息技术有限公司
* @author:[谭磊][leetone123@163.com]
*/
public class Count {

	public int num = 0;
	
	private byte[] lock = new byte[1];
	
	/**
	* @Title: add
	* @Description: 【同步锁的第一种方式：锁住整个方法体】
	* @date 2018年8月29日 上午11:42:17
	* @author:[谭磊][leetone123@163.com]
	* @param     参数
	* @return void    返回类型
	* @throws
	*/
	public synchronized void add() {
		try {
			Thread.sleep(5L);//模仿干活
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		num ++;
		System.out.println("当前是：\t"+Thread.currentThread().getName()+"在干活，干完了："+num);
	}
	
	
	/**
	* @Title: addTwo
	* @Description: 【第二种方式，锁住一个对象，执行效率要高于第一种，因为进入方法也需要消耗资源】
	* @date 2018年8月29日 上午11:42:43
	* @author:[谭磊][leetone123@163.com]
	* @param     参数
	* @return void    返回类型
	* @throws
	*/
	public void addTwo() {
		synchronized(this) {
			//模仿用户干活
			try {
				Thread.sleep(5L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			num++;
			System.out.println(Thread.currentThread().getName()+"已经干完了：\t"+num);
		}
	}
	
	
	/**
	* @Title: addThree
	* @Description: 【生产环境常见的一种错误写法，非线程安全的，但是执行效率最高，毕竟他锁住的对象就是一个字节】
	* @date 2018年8月29日 上午11:45:03
	* @author:[谭磊][leetone123@163.com]
	* @param     参数
	* @return void    返回类型
	* @throws
	*/
	public void addThree() {
		synchronized(lock) {
			//模仿用户干活
			try {
				Thread.sleep(5L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			num++;
			System.out.println(Thread.currentThread().getName()+"已经干完了：\t"+num);
		}
	}
}
